# -*- coding: utf-8 -*-

"""746. 使用最小花费爬楼梯
给你一个整数数组 cost ，其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用，即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。

示例 1：
输入：cost = [10,15,20]
输出：15
解释：你将从下标为 1 的台阶开始。
- 支付 15 ，向上爬两个台阶，到达楼梯顶部。
总花费为 15 。

示例 2：
输入：cost = [1,100,1,1,1,100,1,1,100,1]
输出：6
解释：你将从下标为 0 的台阶开始。
- 支付 1 ，向上爬两个台阶，到达下标为 2 的台阶。
- 支付 1 ，向上爬两个台阶，到达下标为 4 的台阶。
- 支付 1 ，向上爬两个台阶，到达下标为 6 的台阶。
- 支付 1 ，向上爬一个台阶，到达下标为 7 的台阶。
- 支付 1 ，向上爬两个台阶，到达下标为 9 的台阶。
- 支付 1 ，向上爬一个台阶，到达楼梯顶部。
总花费为 6 。

提示：
2 <= cost.length <= 1000
0 <= cost[i] <= 999"""

class Solution:
    """
    递归基础：
        f(0) = 0                                        # 到达标号为 0 的台阶最小花费
        f(1) = 0                                        # 到达标号为 1 的台阶最小花费
        f(2) = min(f(1)+c(1), f(0)+c(0))                # 到达标号为 2 的台阶最小花费
    递归定义：
        f(n) = min(f(n-1)+c(n-1), f(n-2)+c(n-2))        # 到达标号为 n 的台阶最小花费
    cost = [10,15,20], 代表允许分别从0、1、2标号的台阶上爬的费用，所以楼梯顶部应该是 3 标号的台阶
    将递归，按动态规划，转化为递推的状态缓存
    """
    def minCostClimbingStairs(self, cost: list) -> int:
        flr1, flr2, flr3 = 0, 0, 1
        i = 2   # 按边界条件，应该从2号台阶开始算起
        while i <= len(cost):
            flr3 = min(flr2+cost[i-1], flr1+cost[i-2])
            flr1, flr2 = flr2, flr3
            i += 1
        return flr3

if __name__ == '__main__':
    print(Solution().minCostClimbingStairs([10,15,20]))
